package com.ailight.smart.ai.config;

import com.ailight.smart.ai.assembler.AiModelAssembler;
import com.ailight.smart.ai.command.LightModelCommand;
import com.ailight.smart.ai.enums.OperationTypeEnums;
import com.ailight.smart.ai.feign.LightApiFeignFacade;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.model.function.FunctionCallback;
import org.springframework.ai.model.function.FunctionCallbackWrapper;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.function.Function;

@Component
@RequiredArgsConstructor
public class AiToolsConfig {
    private final LightApiFeignFacade lightApiFeignFacade;

    // 天气查询工具
    // 定义参数类
    private record WeatherRequest(String city) {
    }

    // 定义控制灯光的参数类
    private record LightControlRequest(String optName) {
    }

    @Bean
    public FunctionCallback weatherFunctionCallback() {
        // 这个是天气查询工具 自定义查询 并没有调用第三方接口
        // 使用记录类定义参数
        Function<WeatherRequest, String> weatherFunction = (request) -> {
            Map<String, String> weatherData = Map.of(
                    "北京", "晴，温度：22°C，湿度：45%，风速：3m/s",
                    "上海", "晴，温度：-15°C，湿度：10%，风速：2m/s",
                    "广州", "阵雨，温度：28°C，湿度：70%，风速：4m/s",
                    "深圳", "晴，温度：26°C，湿度：55%，风速：3m/s"
            );
            return weatherData.getOrDefault(request.city(), "暂未找到该城市的天气信息");
        };

        return FunctionCallbackWrapper.builder(weatherFunction)
                .withName("getWeather")
                .withDescription("获取指定城市的当前天气信息")
                .withInputType(WeatherRequest.class) // 使用记录类作为输入类型
                .build();
    }

    // 计算器工具
    @Bean
    public FunctionCallback calculatorFunctionCallback() {
        // 这个是计算器工具
        Function<Map<String, Object>, String> calculatorFunction = (params) -> {
            double a = Double.parseDouble(params.get("a").toString());
            double b = Double.parseDouble(params.get("b").toString());
            String operation = params.get("operation").toString();

            try {
                double result = switch (operation.toLowerCase()) {
                    case "add" -> a + b;
                    case "subtract" -> a - b;
                    case "multiply" -> a * b;
                    case "divide" -> {
                        if (b == 0) throw new IllegalArgumentException("除数不能为零");
                        yield a / b;
                    }
                    default -> throw new IllegalArgumentException("不支持的运算类型: " + operation);
                };

                return String.format("%.2f %s %.2f = %.2f", a, getOperationSymbol(operation), b, result);
            } catch (Exception e) {
                return "计算错误: " + e.getMessage();
            }
        };

        return FunctionCallbackWrapper.builder(calculatorFunction)
                .withName("calculate")
                .withDescription("执行数学计算，支持加减乘除运算")
                .build();
    }

    //远程控制智能灯关闭函数
    @Bean
    public FunctionCallback lightControlFunctionCallback() {
        Function<LightControlRequest, String> lightControlFunction = (request) -> {
            // 模拟远程控制智能灯的关闭功能
            // 通过模型返回的参数来获取调用light-api控制模块的接口入参
            if (request.optName.equals("manual_off") || request.optName.equals("turn_light")) {
                return lightApiFeignFacade.lightControl(request.optName);
            }
            LightModelCommand command = AiModelAssembler.getLightModelCommand(OperationTypeEnums.getOperationTypeEnums(request.optName));
            return lightApiFeignFacade.lightControl(command);
        };
        return FunctionCallbackWrapper.builder(lightControlFunction)
                .withName("lightControl")
                .withDescription("直接执行智能灯具控制操作。根据用户的具体需求，从预定义的操作中选择一个执行。" +
                        "操作类型包括：开关灯、切换模式、灯光挡位调节" +
                        "重要：直接执行用户要求的操作，不要考虑当前灯具的状态或模式限制")
                .withInputType(LightControlRequest.class)
                .build();
    }

    private String getOperationSymbol(String operation) {
        return switch (operation.toLowerCase()) {
            case "add" -> "+";
            case "subtract" -> "-";
            case "multiply" -> "×";
            case "divide" -> "÷";
            default -> "?";
        };
    }
}
